
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;

using Swaf;
using Swaf.BizObj;


namespace Swaf.BizObj.fieldValidator
{
	
	/// <summary> The concrete FieldValidator derived class that validates
	/// that an integer (actually a 'long') is within a range.
	/// </summary>
	[Serializable]
	public class IntegerRangeValidator:FieldValidator
	{
		public static void register(IApplication app)
		{
			Swaf.BizObj.BizObjManager bizObjMgr = (Swaf.BizObj.BizObjManager)app.bizObjMgr;
			// Prototype Pattern: adds a prototype object to FieldValidator's (static) "prototypes_" map.
			reg(bizObjMgr, "integer{ws}({integer}){ws}to{ws}({integer})", "integer 3 to 5", 3, 5);
			reg(bizObjMgr, "integer{optional-ws}<={optional-ws}()({integer})", "integer <= 5", - System.Int64.MaxValue, 5);
			reg(bizObjMgr, "integer{optional-ws}>={optional-ws}({integer})()", "integer >= 3", 3, System.Int64.MaxValue);
		}		
		
		/// <summary>Registers the specified pattern as a validator.
		/// </summary>
		protected internal static void  reg(BizObjManager bizObjMgr, string pattern, string example, long min, long max)
		{
			bizObjMgr.registerPrototype(pattern, new IntegerRangeValidator(example, min, max));
		}
		
		public override string validateNoThrow(IBizObj bizObj, string name, string newValue)
		{
			long x = 0;
			try
			{
				x = (long) System.Int64.Parse(newValue);
			}
			catch (System.FormatException e)
			{
				return "Invalid integer: " + e.Message;
			}
			if (x < min_)
				return "Must be >= " + min_;
			if (x > max_)
				return "Must be <= " + max_;
			return null;
		}
		
		protected internal override FieldValidator create(string context, string a, string b, string c)
		{
			return new IntegerRangeValidator(context, a, b);
		}
		
		/// <summary>Constructs a IntegerRangeValidator using the specified name and params.
		/// </summary>
		protected internal IntegerRangeValidator(string context, string a, string b):base(context)
		{
			if (a.Length == 0)
			{
				min_ = - System.Int64.MaxValue;
				max_ = toLong(context, b);
			}
			else if (b.Length == 0)
			{
				min_ = toLong(context, a);
				max_ = System.Int64.MaxValue;
			}
			else
			{
				min_ = toLong(context, a);
				max_ = toLong(context, b);
			}
			if (min_ > max_)
				parseError("min and max of range are backwards: " + context);
		}
		
		/// <summary>Constructs a IntegerRangeValidator using the specified min and max.
		/// </summary>
		protected internal IntegerRangeValidator(string context, long min, long max):base(context)
		{
			min_ = min;
			max_ = max;
		}
		
		/// <summary>This is the minimum value of a valid long.
		/// </summary>
		protected internal long min_;
		
		/// <summary>This is the maximum value of a valid long.
		/// </summary>
		protected internal long max_;
		
		public override string details(string prefix)
		{
			return prefix + "IntegerRangeValidator(\"" + this + "\") { min=" + min_ + ", max=" + max_ + " }";
		}
	}
}